#pragma once

#include <sys/epoll.h>
#include "BufMgr.h"
#include "Buffer.h"
#include "IpcPkgBuf.h"

class CPkgBufMgr;

struct IpcCmdMsg
{
    uint16_t len;
    IpcCmd cmd;
};

/************************************
* CServer:提供epoll功能及IPC功能
************************************/
class CServer
{
public:
    CServer();
    virtual ~CServer();

public:
    virtual bool Init(int *fds);
    virtual bool Start();
    virtual bool Stop();
    virtual bool Destroy();

protected:
    virtual bool ErrorEvent(epoll_event &ee) = 0;    // 发生错误处理事件
    virtual bool InputEvent(epoll_event &ee) = 0;    // 输入事件
    virtual bool OutputEvent(epoll_event &ee) = 0;   // 输出事件
    virtual bool IpcCmdEvent(IpcPkgBuf &pbRecv) = 0; // IPC命令事件

private:
    bool EventHandle();                 // 所有事件的处理
    bool ErrorHandle(epoll_event &ee);  // 错误事件预处理
    bool InputHandle(epoll_event &ee);  // 输入事件预处理
    bool OutputHandle(epoll_event &ee); // 输出事件预处理
    bool IpcRecvHandle();               // IPC接受数据处理
    bool IpcSendHandle();               // IPC发送数据处理
    bool IpcCmdHandle();                // IPC命令预处理
    bool IpcPkgParse();                 // IPC数据解包处理
    void RunStop();                     // CServer层的Stop实际执行

public:
    int IpcSend(void *pSrc, int iLen);              // 提供给其它进程发送IPC数据到本进程
    static int BindAndListen(unsigned short nPort); // 创建绑定监听端口

protected:
    static bool SetNonBlock(int ifd);                              // 设置端口为非阻塞
    bool UpdateEvents(int ifd, int iEvnts, int iOpt, void *pData); // 绑定事件及数据到epoll

protected:
    int m_iefd; // epoll fd
    CBufMgr<> *m_pBufMgr;

private:
    bool m_bRunning;
    epoll_event *m_pEvnts;

    int m_irspfd; // socketpair通讯套接字中的读套接字
    int m_iwspfd; // socketpair通讯套接字中的写套接字

    IpcPkgBuf m_ipb;                // IPC数据包缓冲，缓存一个完整包
    CBuffer<> *m_pIpcRecv;          // IPC接收缓冲
    CBuffer<CSpinLock> *m_pIpcSend; // IPC发送缓冲
};
